﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using Eb;
using Ec;

public class DefUCenterSession : ComponentDef
{
    //---------------------------------------------------------------------
    public override void defAllProp(Dictionary<string, string> map_param)
    {
    }
}

public class ClientUCenterSession<TDef> : Component<TDef> where TDef : DefUCenterSession, new()
{
    //-------------------------------------------------------------------------
    EntityRpcSessionSuperSocketC mSession;
    ClientLoginRequest mClientLoginRequest;
    OnUCenterLogin mOnUCenterLogin;
    float mLoginTm;// 登陆计时，超过5秒未收到消息后关闭连接
    float mLoginTimeout;
    float mHeartbeatTmSpan = 5f;
    float mHeartbeatTm;
    bool mHandled;
    bool mConnected;

    //-------------------------------------------------------------------------
    public override void init()
    {
        EbLog.Note("ClientUCenterSession.init()");

        mClientLoginRequest = (ClientLoginRequest)Entity.getCacheData("ClientLoginRequest");
        mOnUCenterLogin = (OnUCenterLogin)Entity.getCacheData("OnUCenterLogin");
        string login_ip = (string)Entity.getCacheData("LoginIp");
        int login_port = (int)Entity.getCacheData("LoginPort");
        mLoginTimeout = (float)Entity.getCacheData("RequestTimeout");

        mSession = new EntityRpcSessionSuperSocketC(EntityMgr);
        mSession.OnSocketConnected = _onSocketConnected;
        mSession.OnSocketClosed = _onSocketClosed;
        mSession.OnSocketError = _onSocketError;
        mSession.connect(login_ip, login_port);
    }

    //-------------------------------------------------------------------------
    public override void release()
    {
        if (mSession != null)
        {
            mSession.close();
            mSession = null;
        }

        var ucenter = Entity.Parent.getComponent<ClientUCenterSDK4Client<DefUCenterSDK4Client>>();
        ucenter.remove(mClientLoginRequest.acc);

        EbLog.Note("ClientUCenterSession.release()");
    }

    //-------------------------------------------------------------------------
    public override void update(float elapsed_tm)
    {
        if (mSession != null)
        {
            mSession.update(elapsed_tm);
        }

        // 超时判定
        if (mLoginTimeout > 0f)
        {
            mLoginTm += elapsed_tm;
            if (mLoginTm > mLoginTimeout && !mHandled)
            {
                mLoginTm = 0f;
                if (mSession != null)
                {
                    mSession.close();
                    mSession = null;
                }
            }
        }

        // 心跳
        mHeartbeatTm += elapsed_tm;
        if (mConnected && mSession != null & mHeartbeatTm > mHeartbeatTmSpan)
        {
            mHeartbeatTm = 0f;
            rpcBySession(mSession, (ushort)_eUCenterMethodType.client2loginHeartbeat);
        }
    }

    //-------------------------------------------------------------------------
    public override void handleEvent(object sender, EntityEvent e)
    {
    }

    //-------------------------------------------------------------------------
    // 响应登陆请求
    public void login2clientOnLogin(ClientLoginResponse client_login_response)
    {
        // 通知应用层
        if (mOnUCenterLogin != null && !mHandled)
        {
            mHandled = true;
            mOnUCenterLogin(client_login_response);
        }

        // 断开连接
        if (mSession != null)
        {
            mSession.close();
            mSession = null;
        }
    }

    //-------------------------------------------------------------------------
    void _onSocketConnected(object client, EventArgs args)
    {
        EbLog.Note("ClientUCenterSession._onSocketConnected() client2loginLogin acc=" + mClientLoginRequest.acc);

        mConnected = true;
        rpcBySession(mSession, (ushort)_eUCenterMethodType.client2loginLogin, mClientLoginRequest);
    }

    //-------------------------------------------------------------------------
    void _onSocketClosed(object client, EventArgs args)
    {
        EbLog.Note("ClientUCenterSession._onSocketClosed()");

        mSession = null;

        // 通知应用层
        if (mOnUCenterLogin != null && !mHandled)
        {
            mHandled = true;

            ClientLoginResponse client_login_response = new ClientLoginResponse();
            client_login_response.result = eLoginResult.serverReject;
            client_login_response.acc_id = 0;
            client_login_response.token = "";
            client_login_response.acc = mClientLoginRequest.acc;
            client_login_response.map_param = mClientLoginRequest.map_param;
            mOnUCenterLogin(client_login_response);
        }

        EntityMgr.destroyEntity(Entity);
    }

    //-------------------------------------------------------------------------
    void _onSocketError(object client, SocketErrorEventArgs args)
    {
        EbLog.Note("ClientUCenterSession._onSocketError()");

        mSession = null;

        // 通知应用层
        if (mOnUCenterLogin != null && !mHandled)
        {
            mHandled = true;

            ClientLoginResponse client_login_response = new ClientLoginResponse();
            client_login_response.result = eLoginResult.connectFailed;
            client_login_response.acc_id = 0;
            client_login_response.token = "";
            client_login_response.acc = mClientLoginRequest.acc;
            client_login_response.map_param = mClientLoginRequest.map_param;
            mOnUCenterLogin(client_login_response);
        }

        EntityMgr.destroyEntity(Entity);
    }
}
